import * as fs from "fs/promises";
import * as path from "path";

export interface PluginInstallRequest {
  projectPath: string;
  pluginUrl?: string;
  pluginName?: string;
  pluginSource?: string; // URL or local path or npm package
  enabled?: boolean;
}

export interface PluginConfig {
  name: string;
  status: boolean;
  description: string;
  parameters: Record<string, any>;
}

// Popular RPG Maker MZ plugins registry
const PLUGIN_REGISTRY: Record<string, string> = {
  "VisuMZ_0_CoreEngine": "https://raw.githubusercontent.com/VisuStella/VisualNovelChoice/master/VisuMZ_0_CoreEngine.js",
  // Add more popular plugins here
};

export async function installPlugin(request: PluginInstallRequest): Promise<{ success: boolean; plugin?: string; error?: string }> {
  try {
    const pluginsDir = path.join(request.projectPath, "js", "plugins");
    await fs.mkdir(pluginsDir, { recursive: true });

    let pluginContent: string;
    let pluginName: string;

    // Determine plugin source
    if (request.pluginSource) {
      if (request.pluginSource.startsWith("http")) {
        // Download from URL
        const response = await fetch(request.pluginSource);
        if (!response.ok) {
          return { success: false, error: `Failed to download plugin: ${response.statusText}` };
        }
        pluginContent = await response.text();
        pluginName = request.pluginName || path.basename(new URL(request.pluginSource).pathname);
      } else if (await fs.access(request.pluginSource).then(() => true).catch(() => false)) {
        // Local file
        pluginContent = await fs.readFile(request.pluginSource, "utf-8");
        pluginName = request.pluginName || path.basename(request.pluginSource);
      } else {
        return { success: false, error: "Invalid plugin source" };
      }
    } else if (request.pluginName && PLUGIN_REGISTRY[request.pluginName]) {
      // From registry
      const url = PLUGIN_REGISTRY[request.pluginName];
      const response = await fetch(url);
      if (!response.ok) {
        return { success: false, error: `Failed to download plugin from registry` };
      }
      pluginContent = await response.text();
      pluginName = request.pluginName;
    } else {
      return { success: false, error: "No valid plugin source provided" };
    }

    // Save plugin file
    const pluginPath = path.join(pluginsDir, pluginName);
    await fs.writeFile(pluginPath, pluginContent, "utf-8");

    // Update plugins.js
    await updatePluginsConfig(request.projectPath, pluginName, request.enabled !== false);

    return { success: true, plugin: pluginName };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

async function updatePluginsConfig(projectPath: string, pluginName: string, enabled: boolean): Promise<void> {
  const pluginsJsPath = path.join(projectPath, "js", "plugins.js");

  let pluginsConfig: PluginConfig[] = [];

  // Read existing config if exists
  try {
    const content = await fs.readFile(pluginsJsPath, "utf-8");
    const match = content.match(/var \$plugins\s*=\s*(\[[\s\S]*?\]);/);
    if (match) {
      pluginsConfig = JSON.parse(match[1]);
    }
  } catch {
    // File doesn't exist, will create new
  }

  // Add or update plugin
  const existingIndex = pluginsConfig.findIndex(p => p.name === pluginName);
  const pluginEntry: PluginConfig = {
    name: pluginName.replace(".js", ""),
    status: enabled,
    description: "",
    parameters: {}
  };

  if (existingIndex >= 0) {
    pluginsConfig[existingIndex] = pluginEntry;
  } else {
    pluginsConfig.push(pluginEntry);
  }

  // Write back
  const content = `// Generated by RPG Maker MZ MCP
var $plugins = ${JSON.stringify(pluginsConfig, null, 2)};
`;

  await fs.writeFile(pluginsJsPath, content, "utf-8");
}

export async function listInstalledPlugins(projectPath: string): Promise<{ success: boolean; plugins?: PluginConfig[]; error?: string }> {
  try {
    const pluginsJsPath = path.join(projectPath, "js", "plugins.js");
    const content = await fs.readFile(pluginsJsPath, "utf-8");
    const match = content.match(/var \$plugins\s*=\s*(\[[\s\S]*?\]);/);

    if (match) {
      const plugins = JSON.parse(match[1]);
      return { success: true, plugins };
    }

    return { success: true, plugins: [] };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

export async function uninstallPlugin(projectPath: string, pluginName: string): Promise<{ success: boolean; error?: string }> {
  try {
    // Remove from plugins.js
    const pluginsJsPath = path.join(projectPath, "js", "plugins.js");
    const content = await fs.readFile(pluginsJsPath, "utf-8");
    const match = content.match(/var \$plugins\s*=\s*(\[[\s\S]*?\]);/);

    if (match) {
      let plugins = JSON.parse(match[1]);
      plugins = plugins.filter((p: PluginConfig) => p.name !== pluginName.replace(".js", ""));
      const newContent = `// Generated by RPG Maker MZ MCP\nvar $plugins = ${JSON.stringify(plugins, null, 2)};\n`;
      await fs.writeFile(pluginsJsPath, newContent, "utf-8");
    }

    // Delete plugin file
    const pluginPath = path.join(projectPath, "js", "plugins", pluginName);
    await fs.unlink(pluginPath);

    return { success: true };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

export async function enablePlugin(projectPath: string, pluginName: string, enabled: boolean): Promise<{ success: boolean; error?: string }> {
  try {
    const pluginsJsPath = path.join(projectPath, "js", "plugins.js");
    const content = await fs.readFile(pluginsJsPath, "utf-8");
    const match = content.match(/var \$plugins\s*=\s*(\[[\s\S]*?\]);/);

    if (match) {
      const plugins = JSON.parse(match[1]);
      const plugin = plugins.find((p: PluginConfig) => p.name === pluginName.replace(".js", ""));

      if (plugin) {
        plugin.status = enabled;
        const newContent = `// Generated by RPG Maker MZ MCP\nvar $plugins = ${JSON.stringify(plugins, null, 2)};\n`;
        await fs.writeFile(pluginsJsPath, newContent, "utf-8");
        return { success: true };
      }

      return { success: false, error: "Plugin not found" };
    }

    return { success: false, error: "No plugins config found" };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}